﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using MyFloridaHouse.libSvCommonUtilities;
using MyFloridaHouse.libSvOpenDistricts.DataService;
using MyFloridaHouse.libSvOpenDistricts.StorageIsolated;
using MyFloridaHouse.libSvUtilities;
using MyFloridaHouse.ServiceConn.DistrBldrSvcRef;
using System.Windows;

namespace MyFloridaHouse.libSvOpenDistricts.Districts
{
    public delegate void DistrictPlanTypesInitializedEventHandler();

    public class DistrictPlanTypes : INotifyPropertyChanged
    {
        #region events
        public static event DistrictPlanTypesInitializedEventHandler DistrictPlanTypesInitialized;

        private static void RaiseCensusGeometryInitialized(object sender)
        {
            if (DistrictPlanTypesInitialized != null)
            {
                DistrictPlanTypes._districtPlanTypesInstance.isInitializeComplete = true;
                DistrictPlanTypesInitialized();
            }
            else
            {
                // todo: Log this error
                throw (new NotImplementedException("No Subscribers to DistrictPlanTypesInitialized Event"));
            }
        }

        #endregion

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion


        private bool _isInitializeComplete = false;
        public bool isInitializeComplete
        {
            get { return _isInitializeComplete; }
            set { if (_isInitializeComplete != value) { _isInitializeComplete = value; NotifyPropertyChanged("isInitializeComplete"); } }
        }

        private bool _isInitializeError = false;
        public bool isInitializeError
        {
            get { return _isInitializeError; }
            set { if (_isInitializeError != value) { _isInitializeError = value; NotifyPropertyChanged("isInitializeError"); } }
        }

        private static DistrictPlanTypes _districtPlanTypesInstance;
        public static DistrictPlanTypes districtPlanTypesInstance
        {
            get { return _districtPlanTypesInstance; }
        }

        private int _districtPlanTypeSelectedIndex = -1;
        public int districtPlanTypeSelectedIndex
        {
            get { return _districtPlanTypeSelectedIndex; }
            set
            {
                if (_districtPlanTypeSelectedIndex != value)
                {
                    _districtPlanTypeSelectedIndex = value;
                    // the plan type selection has changed, let's reset the district count to match
                    // districtCount textbox is not bound to the list directly because we want the user to be able to enter their own number of districts
                    // therefore, we bind the textbox directly to the districtCount variable
                    districtPlanTypeDistrictCount = 0;
                    if ((value >= 0) & (value < districtPlanTypeList.Count))
                    {
                        if (districtPlanTypeList[value] != null)
                        {
                            districtPlanTypeDistrictCount = districtPlanTypeList[value].districtCount;
                        }
                    }
                    NotifyPropertyChanged("districtPlanTypeSelectedIndex");
                    NotifyPropertyChanged("districtPlanTypeDisplayName");
                }
            }
        }

        public string districtPlanTypeDisplayName
        {
            get
            {
                if (_districtPlanTypeList == null)
                {
                    return "District Plan Type";
                }
                else
                {
                    if ((_districtPlanTypeSelectedIndex < 0) | (_districtPlanTypeSelectedIndex > _districtPlanTypeList.Count - 1))
                    {
                        return "District Plan Type";
                    }
                    else
                    {
                        return "(" + _districtPlanTypeList[_districtPlanTypeSelectedIndex].displayName + ")";
                    }
                }
            }
        }

        private ObservableCollection<DistrictPlanTypeDTO> _districtPlanTypeList = new ObservableCollection<DistrictPlanTypeDTO>();
        public ObservableCollection<DistrictPlanTypeDTO> districtPlanTypeList
        {
            get { return _districtPlanTypeList; }
            set { if (_districtPlanTypeList != value) { _districtPlanTypeList = value; NotifyPropertyChanged("districtPlanTypeList"); } }
        }


        private int _districtPlanTypeDistrictCount;
        public int districtPlanTypeDistrictCount
        {
            get { return _districtPlanTypeDistrictCount; }
            set 
            { 
                if (_districtPlanTypeDistrictCount != value) 
                { 
                    _districtPlanTypeDistrictCount = value;
                    NotifyPropertyChanged("districtPlanTypeDistrictCount"); 
                } 
            }
        }



        public string selectedDistrictPlanTypeID
        {
            get { return districtPlanTypeList[districtPlanTypeSelectedIndex].districtPlanTypeID; }
        }

        public string selectedDistrictPlanTypeDisplayName
        { 
            get { return districtPlanTypeList[districtPlanTypeSelectedIndex].displayName; }
        }

        public DistrictPlanTypes(ServiceDAL serviceDAL)
        {
            // when the object is created, store a reference to it in the static class
            // That way anything that needs to access the instance methods can do so without passing around references all over the place
            _districtPlanTypesInstance = this;

            ServiceDAL.GetDistrictPlanTypeCompleted += OnServiceDALGetDistrictPlanTypesCompleted;
            serviceDAL.GetDistrictPlanTypes();
        }


        private void OnServiceDALGetDistrictPlanTypesCompleted(DistrictPlanTypeSTO sto)
        {
            try
            {
                if (sto.packedDataList.Length > 0)
                {

                    byte[] serializedData = CompressionManager.DecompressToByteArray(sto.packedDataList);
                    DistrictPlanTypeListDTO districtPlanTypeDeserializeList = (DistrictPlanTypeListDTO)SerializationManager.Deserialize(typeof(DistrictPlanTypeListDTO), serializedData);

                    // load up the data
                    districtPlanTypeList.Clear();
                    //TODO: I think you can convert an Observablecollection to List in one statement using a lambda expression - but I can't remember where I saw it! (somewhere in our code I think)
                    var districtPlanTypeQuery = from districtPlanType in districtPlanTypeDeserializeList.districtPlanTypeList
                                                select districtPlanType;
                    foreach (var districtPlanType in districtPlanTypeQuery)
                    {
                        districtPlanTypeList.Add(districtPlanType);
                    }

                    // save for quick load next time
                    IsolatedStorageHelper.SaveDistrictPlanTypes(districtPlanTypeList);

                }
                else
                {
                    try
                    {
                        // perform quick load
                        districtPlanTypeList = IsolatedStorageHelper.LoadDistrictPlanTypes();
                    }
                    catch(Exception ex)
                    {
                        // for any load error, delete the file - this will force the system to get the file from the cloud at next startup
                        IsolatedStorageHelper.DeleteDistrictPlanTypes();
                        throw ex;
                    }

                }
                districtPlanTypeSelectedIndex = 0;
            }
            catch (Exception ex)
            {
                isInitializeError = true;
                MessageBox.Show("There was an error loading the DistrictPlanTypes.  Please refresh the page to restart");
            }
            DistrictPlanTypes.RaiseCensusGeometryInitialized(this);
        }


		public string GetDistrictPlanTypeNameFromID(string districtPlanTypeID)
        {
            string districtPlanTypeName = "";
            foreach (var typ in districtPlanTypeList)
            {
                if (typ.districtPlanTypeID == districtPlanTypeID)
                {
                    districtPlanTypeName = typ.displayName;
                }
            }
            return districtPlanTypeName;
        }
	}


}
